using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Links;
using Sitecore.Web.UI.WebControls;
using SunGard.Corp.Core.Lookups;
using SunGard.Corp.Core.Utilities;

namespace SitecoreFacade.SitecoreItems
{
    /// <summary>
    /// Class representing fields in a Sitecore data item.
    /// </summary>
    public class SitecoreItem : ISitecoreItem
    {
        private Item item;

        public SitecoreItem(Item item)
        {
            this.item = item;
        }

        public Item Item
        {
            get { return item; }
        }

        /// <summary>
        /// ID of item in Sitecore, which is a string representation of a Guid
        /// </summary>
        public string ID
        {
            get
            {
                if (item != null)
                {
                    return item.ID.ToString();
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Short ID of item in Sitecore, which is a string representation of a Guid without dashes and braces
        /// </summary>
        public string ShortID
        {
            get
            {
                if (item != null)
                {
                    return item.ID.ToShortID().ToString();
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Name of item
        /// </summary>
        public string Name
        {
            get
            {
                if (item != null)
                {
                    return item.Name;
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Title of Sitecore item
        /// </summary>
        public string Title
        {
            get
            {
                if (item != null && item.Fields["title"] != null)
                {
                    return CleanUpAmpersands(item.Fields["title"].ToString().Trim());
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Meta title associated with item
        /// </summary>
        public string MetaTitle
        {
            get
            {
                if (item != null && item.Fields["metatitle"] != null)
                {
                    return item.Fields["metatitle"].ToString().Trim();
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Meta keywords associated with item
        /// </summary>
        public string MetaKeywords
        {
            get
            {
                if (item != null && item.Fields["metakeywords"] != null)
                {
                    return item.Fields["metakeywords"].ToString();
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Meta description associated with item
        /// </summary>
        public string MetaDescription
        {
            get
            {
                if (item != null && item.Fields["metadescription"] != null)
                {
                    return item.Fields["metadescription"].ToString();
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Friendly URL of item
        /// </summary>
        public string FriendlyUrl
        {
            get
            {
                if (item != null)
                {
                    return GetItemUrl();
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Sitecore path of item
        /// </summary>
        public string Path
        {
            get
            {
                if (item != null)
                {
                    return item.Paths.Path;
                }
                return string.Empty;
            }
        }

        public string Render(string fieldName)
        {
            ISitecoreField field = GetSitecoreField(fieldName);
            if (field != null)
            {
                if (field.IsOfType(SitecoreFieldType.RichText))
                {
                    return HTMLParsedToEnsureLinksAndImagesHaveFullyQualifiedPaths(FieldRenderer.Render(item, fieldName).Trim());
                }
                return FieldRenderer.Render(item, fieldName).Trim();
            }
            return string.Empty;
        }

        private string HTMLParsedToEnsureLinksAndImagesHaveFullyQualifiedPaths(string valueToParse)
        {
            return HTMLUtility.UpdateImageSourceAndHrefTagsToHaveFullyQualifiedPaths(valueToParse);
        }

        /// <summary>
        /// Name of template associated with item
        /// </summary>
        public string TemplateName
        {
            get
            {
                if (item != null)
                {
                    return item.TemplateName;
                }
                return string.Empty;
            }
        }

        /// <summary>
        /// Date item was last updated
        /// </summary>
        public DateTime LastUpdatedDate
        {
            get
            {
                if (item != null)
                {
                    return DateUtility.ConvertSitecoreDateTimeFormatToCleanDateTimeFormat(new SitecoreField(item.Fields["__Updated"]));
                }
                return new DateTime();
            }
        }

        /// <summary>
        /// Get children of item
        /// </summary>
        public List<ISitecoreItem> GetChildren()
        {                        
            List<ISitecoreItem> children = new List<ISitecoreItem>();
            if (item != null)
            {
                foreach (Item child in item.Children)
                {
                    ISitecoreItem sitecoreItem = new SitecoreItem(child);
                    children.Add(sitecoreItem);
                }
            }
            return children;
        }

        /// <summary>
        /// Get children of item that have the given template
        /// </summary>
        public List<ISitecoreItem> GetChildrenWithSpecifiedTemplate(string templateName)
        {
            List<ISitecoreItem> children = new List<ISitecoreItem>();
            if (item != null)
            {
                foreach (Item child in item.Children)
                {
                    if (child.TemplateName.ToLower() == templateName.ToLower())
                    {
                        ISitecoreItem sitecoreItem = new SitecoreItem(child);
                        children.Add(sitecoreItem);
                    }
                }
            }
            return children;
        }

        /// <summary>
        /// Get children of item that have a template name in the given list of names
        /// </summary>
        public List<ISitecoreItem> GetChildrenWithSpecifiedTemplates(params string[] templateNames)
        {
            List<ISitecoreItem> children = new List<ISitecoreItem>();
            if (item != null)
            {
                foreach (Item child in item.Children)
                {
                    foreach (var name in templateNames)
                    {
                        if (child.TemplateName.ToLower() == name.ToLower())
                        {
                            ISitecoreItem sitecoreItem = new SitecoreItem(child);
                            children.Add(sitecoreItem);
                        }   
                    }                    
                }
            }
            return children;
        }

        /// <summary>
        /// Get a count of children that have the specified template
        /// </summary>
        /// <param name="templateName">Name of the template</param>
        /// <returns></returns>
        public int GetNumberOfChildrenWithSpecifiedTemplate(string templateName)
        {
            int numWithSpecifiedTemplate = 0;
            if (item != null)
            {
                foreach (Item child in item.Children)
                {
                    if (child.TemplateName.ToLower() == templateName.ToLower())
                    {
                        numWithSpecifiedTemplate++;
                    }
                }
            }
            return numWithSpecifiedTemplate;
        }

        /// <summary>
        /// Retrieve a field from the item with the given name
        /// </summary>
        /// <param name="fieldName">Name of field we are retrieving from the item</param>
        public ISitecoreField GetSitecoreField(string fieldName)
        {
            ISitecoreField sitecoreField = null;
            if (item != null)
            {
                Field field = item.Fields[fieldName.ToLower()];
                if (field != null)
                {
                    sitecoreField = new SitecoreField(item.Fields[fieldName.ToLower()]);
                }
            }
            return sitecoreField;
        }

        /// <summary>
        /// Parent of the item
        /// </summary>
        public ISitecoreItem Parent
        {
            get
            {
                ISitecoreItem parent = null;
                if (item != null && item.Parent != null)
                {
                    parent = new SitecoreItem(item.Parent);
                }
                return parent;
            }
        }

        private string GetItemUrl()
        {
            string initialUrl = UrlUtility.WebsiteRootURL() + LinkManager.GetItemUrl(item).ToLower().Trim();
            initialUrl = RemoveLanguageAndSiteSpecificPortionsFromUrl(initialUrl);
            initialUrl = RemoveSitecoreContentFromUrlIfNotInPageEditingMode(initialUrl);
            return initialUrl;
        }

        private string RemoveSitecoreContentFromUrlIfNotInPageEditingMode(string url)
        {
            if (!Sitecore.Context.PageMode.IsPageEditor)
            {
                // Remove site-specific URLs - added due to the "sites" section in the web.config.  
                url = url.Replace("/financialsystems/sitecore/content/", "/");
                url = url.Replace("/publicsector/sitecore/content/", "/");
                url = url.Replace("/corporate/sitecore/content/", "/");

                url = url.Replace("/sitecore/content/", "/");
            }
            return url;
        }

        private string RemoveLanguageAndSiteSpecificPortionsFromUrl(string url)
        {
            // Remove language specific portion
            url = url.Replace("/en/", "/").Replace("/en.aspx", "/");
            return url;
        }

        private string CleanUpAmpersands(string s)
        {
            string patterm = @"\s?&[^amp;]\s?";
            return Regex.Replace(s, patterm, " &amp; ");
        }
    }
}
